package array;


/**
 * @author huang (1431471764@qq.com)
 * @date 2025/8/7 07:44
 */

import java.util.HashMap;

/**
 * @author 随风coding
 * @version 1.0
 * @date 2025/8/7 07:44
 * @description: 你正在探访一家农场，农场从左到右种植了一排果树。这些树用一个整数数组 fruits 表示，其中 fruits[i] 是第 i 棵树上的水果 种类 。
 * <p>
 * 你想要尽可能多地收集水果。然而，农场的主人设定了一些严格的规矩，你必须按照要求采摘水果：
 * <p>
 * 你只有 两个 篮子，并且每个篮子只能装 单一类型 的水果。每个篮子能够装的水果总量没有限制。
 * 你可以选择任意一棵树开始采摘，你必须从 每棵 树（包括开始采摘的树）上 恰好摘一个水果 。采摘的水果应当符合篮子中的水果类型。每采摘一次，你将会向右移动到下一棵树，并继续采摘。
 * 一旦你走到某棵树前，但水果不符合篮子的水果类型，那么就必须停止采摘。
 * 给你一个整数数组 fruits ，返回你可以收集的水果的 最大 数目。
 */

public class FruitIntoBuckt {
    public static int totalFruit(int[] fruits) {
        int left = 0;
        int maxFruits = 0;
        //创建一个水果篮子
        HashMap<Integer, Integer> fruitBucket = new HashMap<Integer, Integer>();
        //循环开始摘水果
        for (int right = 0; right < fruits.length; right++) {
            //当前水果
            int currentFruit = fruits[right];
            //放进篮子里
            fruitBucket.put(currentFruit, fruitBucket.getOrDefault(currentFruit, 0) + 1);
            //如果篮子的大小大于2 就要开始移动left 开始丢弃水果了
            while (fruitBucket.size() > 2) {
                //获取left指向的水果
                int leftFruit = fruits[left];
                //开始丢水果
                fruitBucket.put(leftFruit, fruitBucket.get(leftFruit) - 1);
                //如果该水果在篮子里的数量为0 那就删除这个建（位置）
                if (fruitBucket.get(leftFruit) == 0) {
                    fruitBucket.remove(leftFruit);
                }
                left++;
            }
            //每一次for循环统计一下最大水果数量
            maxFruits = Math.max(maxFruits, (right - left) + 1);
        }
        return maxFruits;
    }

    public static void main(String[] args) {
        // 测试实例 1：基础场景（最长窗口在中间）
        int[] fruits1 = {1, 2, 1, 2, 3};
        System.out.println("测试1 输入：[1,2,1,2,3] → 预期输出：4，实际输出：" + totalFruit(fruits1));

        // 测试实例 2：所有水果同一种（边界情况）
        int[] fruits2 = {5, 5, 5, 5, 5};
        System.out.println("测试2 输入：[5,5,5,5,5] → 预期输出：5，实际输出：" + totalFruit(fruits2));

        // 测试实例 3：三种水果，最长窗口在末尾
        int[] fruits3 = {1, 3, 2, 2, 2, 3};
        System.out.println("测试3 输入：[1,3,2,2,2,3] → 预期输出：4，实际输出：" + totalFruit(fruits3));

        // 测试实例 4：第三种水果出现在开头
        int[] fruits4 = {3, 1, 2, 1, 2, 1};
        System.out.println("测试4 输入：[3,1,2,1,2,1] → 预期输出：5，实际输出：" + totalFruit(fruits4));

        // 测试实例 5：只有两个元素（最小有效输入）
        int[] fruits5 = {2, 3};
        System.out.println("测试5 输入：[2,3] → 预期输出：2，实际输出：" + totalFruit(fruits5));

        // 测试实例 6：第三种水果连续出现（多次收缩窗口）
        int[] fruits6 = {1, 1, 2, 2, 3, 3, 3};
        System.out.println("测试6 输入：[1,1,2,2,3,3,3] → 预期输出：5，实际输出：" + totalFruit(fruits6));

        // 测试实例 7：空数组（边界情况，返回0）
        int[] fruits7 = {};
        System.out.println("测试7 输入：[] → 预期输出：0，实际输出：" + totalFruit(fruits7));

        // 测试实例 8：单元素数组（边界情况）
        int[] fruits8 = {4};
        System.out.println("测试8 输入：[4] → 预期输出：1，实际输出：" + totalFruit(fruits8));

        // 测试实例 9：最长窗口在开头
        int[] fruits9 = {1, 1, 2, 3, 4, 5};
        System.out.println("测试9 输入：[1,1,2,3,4,5] → 预期输出：3，实际输出：" + totalFruit(fruits9));

        // 测试实例 10：复杂穿插（多次收缩）
        int[] fruits10 = {1, 2, 3, 2, 2, 1, 1, 3};
        System.out.println("测试10 输入：[1,2,3,2,2,1,1,3] → 预期输出：5，实际输出：" + totalFruit(fruits10));
    }
}
